package ViewListener;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;

import Command.Command;
import Model.CheckerState;

public class SqlHighlightChecker {

	public SqlHighlightChecker()
	{
		
	}
	
	private void CheckForKeywordHighLight(SqlEditorThread t, String text)
	{
		String lowerText = text.toLowerCase();
		String[] keys = Command.keywords;
		for(int i = 0 ; i < keys.length; i++)
		{
			if(lowerText.contains(keys[i]))
			{
				setForAllKey(lowerText, keys[i], t, 0);
			}
		}
	}
	
	private int setForAllKey(String fullText, String key, SqlEditorThread t, int index)
	{
		int ret = fullText.indexOf(key, index);		
		if(ret == -1)
			return 0;
		
		int numOfLineFeed = countFeedline(fullText, ret);
		if(ret > 0 )
		{
			if (
					fullText.charAt(ret - 1) == ' ' ||
					fullText.charAt(ret - 1) == '\n' && 
					(
							(
									fullText.length() > ret + key.length() && 
									( 
											fullText.charAt(ret + key.length())== ' ' || 
											( fullText.length() > ret + key.length() + 1 && fullText.charAt(ret + key.length() + 1)== '\n')|| 
											( fullText.length() == ret + key.length() + 1 && fullText.charAt(ret + key.length())== '\n')
									)
							) ||
							fullText.length() == ret + key.length()
					) 
				)
			{
				t.setKeyword(ret - numOfLineFeed, key.length());
			}
		}
		else if (
					(
							fullText.length() > ret + key.length() &&
							(
									fullText.charAt(ret + key.length())== ' '||
									
									( fullText.length() > ret + key.length() + 1 && fullText.charAt(ret + key.length() + 1) == '\n')|| 
									( fullText.length() == ret + key.length() + 1 && fullText.charAt(ret + key.length())== '\n')
							)
					) ||
					fullText.length() == ret + key.length()
				)
		{
			t.setKeyword(ret - numOfLineFeed, key.length());
		}
		
		return setForAllKey(fullText, key, t, ret + 1);
	}
	/**
	 * Count feed line from text[0] to index
	 * @param text
	 * @param index
	 */
	private int countFeedline(String text, int index)
	{
		int countBreak = 0;
		if(index > text.length())
			index = text.length();
		
		for(int i = 0 ; i < index; i++)
		{
			char c = text.charAt(i);
			
			if( c == '\n')
				countBreak++;
		}
		
		return countBreak;
	}
	
	/**
	 * Check and set color for characters in SQL Editor.
	 * @param t SQLEditor thread
	 * @param text String need to check
	 */
	public void CheckForHighLight(SqlEditorThread t, String text)
	{
		// Check for text, commend, normal
		CheckerState state = new CheckerState();
		int breakCount = 0;
		CharacterIterator it = new StringCharacterIterator(text);
		
		char c;
		int i = 0;
		while((c = it.next()) != CharacterIterator.DONE)
		{					
			if( c == '\n')
				breakCount++;
			
			switch(state.getState())
			{
			case CheckerState.Comment:							
				if(text.charAt(i-1) == '\n')
				{
					if(text.charAt(i) == '\'')
					{
						// Comment case -> Text case
						state.setState(CheckerState.Text, i - breakCount);
						t.setText(state.getIndex(), i - state.getIndex() + 1 + breakCount);
					}
					else
					{
						// Comment case -> Normal case
						state.setState(CheckerState.Normal, i - breakCount);
						t.setNormal(state.getIndex(), i - state.getIndex() + 1 + breakCount);
					}
				}		
				
				else
					t.setComment(state.getIndex(), i - state.getIndex() + 1 + breakCount);	
				break;
			case CheckerState.Normal:
				if(i > 0 && text.charAt(i - 1) == '-' && text.charAt(i) == '-')
				{
					// Normal case -> Comment case
					state.setState(CheckerState.Comment, i - 1 - breakCount );	
					
					t.setComment(state.getIndex(), i - state.getIndex() + 1 + breakCount);	
				}
				else if(text.charAt(i) == '\'')
				{
					// Normal case -> Text case
					state.setState(CheckerState.Text, i - breakCount);
					t.setText(state.getIndex(), i - state.getIndex() + 1 + breakCount);
				}
				else
					t.setNormal(state.getIndex(), i - state.getIndex() + 1 + breakCount);		
				break;
			case CheckerState.Text:
				if(i > 0 && text.charAt(i - 1) == '\'' && i - state.getIndex() > 1 + breakCount)
				{					
					// Text case -> Normal case
					state.setState(CheckerState.Normal, i - breakCount);
					t.setNormal(state.getIndex(), i - state.getIndex() + 1 + breakCount);
				}
				else
					t.setText(state.getIndex(), i - state.getIndex() + 1 + breakCount);
				break;				
				
			}
			
			i++;
		}
		

		// Check for keyword
		CheckForKeywordHighLight(t, text);
	}
}
